Ext.ns('TaxonTagger');
TaxonTagger.taggerpanel = function(config){

	this.urlCombo = new Ext.form.ComboBox({
			store: {
					xtype: 'arraystore'
				,	fields: ['url']
			}
		,	displayField: 'url'
		,	scope: this
		,	typeAhead: true
		,	mode: 'local'
		,	triggerAction: 'all'
		,	emptyText: this.txtemptyText
		,	selectOnFocus: true
		,	allowBlank: false
		,	blankText: this.txtblankText
		,	vtype: 'url'
		,	urlText: this.txtUrlText
		,	width: 300
	});

	this.markScientificName = new Ext.Button({
			text: this.txtMarkName
		,	iconCls: 'icon_mark'
		,	ref: ''
		,	tooltip: this.txtMarkNameTip
		,	scope: this
		,	hidden: true
		,	handler: function() {
/*																
				var sel = "";
				if(Ext.getCmp('mifp').getFrameWindow().window.getSelection) {
					sel = Ext.getCmp('mifp').getFrameWindow().getSelection();
				} else if(Ext.getCmp('mifp').getFrameWindow().document.getSelection) {
					sel = Ext.getCmp('mifp').getFrameWindow().document.getSelection();
				} else {
					var selection = Ext.getCmp('mifp').getFrameWindow().document.selection && Ext.getCmp('mifp').getFrameWindow().document.selection.createRange();
					if(selection.text) {
						sel = selection.text;
					}
				}
*/							
				sel = Ext.getCmp('mifp').getFrameWindow().window.getSelection().toString();
				sel = sel.replace(/^\s*|\s*$/g,'');
				if (Ext.isEmpty(sel)) {
					TaxonTagger.Notice.msg(this.txtNoticeTitle, this.msgEmptyMark);
				} else {
					TaxonTagger.currentDocument.customWords.push(sel.trim());
					TaxonTagger.currentDocument.customWords.push(sel.trim);
					this.markSciName(sel);
					this.updateLocalStorage();
				}
			}
	});
			
	var serviceName = Ext.decode(localStorage.getItem("settings")) || Config;
	var urlList = Ext.decode(localStorage.getItem("storedUrls")) || [Config.baseUrl + 'sample.html'];
	this.urlCombo.store.loadData(Ext.zip(urlList), true);

	Ext.apply(this, config, {
			id: 'mifp'
		,	border: false
		,	region: 'center'
		,	iconCls: 'icon_txt'
		,	scope: this
		,	lasturlLoaded: ''
		,	lastService: serviceName["general"]["nfServer"]
		,	firstLoad: true
		,	defaultSrc: 'resources/html/blank-'+lang+'.html'
		,	autoScroll: true
		,	tbar: [
					this.txtUrlField
				, this.urlCombo
				, '&nbsp;', {
						text: this.txtLoadBtn
					,	iconCls: 'icon_load'	
					,	scope: this 
					,	tooltip: this.txtLoadBtnTip
					,	handler: function() {
							this.loadDocument( this.urlCombo.getValue() );
						}
			}, '&nbsp;', this.markScientificName, '&nbsp;', {
					text: this.txtToggleName
				,	ref:'../toggleScientificName'
				,	id: 'btntoggle'
				,	tooltip: this.txtToggleNameTip
				,	scope: this
				, iconCls: 'icon_fullname'
				, hidden: true
				, xtype: 'button'
				, allowDepress: true
				, enableToggle: true
				, toggleHandler: function( btn, state ) {
						var f = Ext.getCmp('mifp').getFrameDocument().body;		
						Ext.each(Ext.fly(f).select("span.tt-sciname").elements, function(el) {
							el.innerHTML = (Ext.getCmp('btntoggle').pressed) ? el.attributes.getNamedItem("scientificname").value : el.attributes.getNamedItem("verbatim").value;
						});  
					}
			}, '->', {
					iconCls: 'icon_page'
				,	ref:'../webLink'	
				,	scope: this
				, 	hidden: true
				,	tooltip: this.txtWeblinkLocalTip	
			} , '&nbsp;' , {
					iconCls: 'x-tbar-loading'
				,	ref:'../resetLocal'	
				,	scope: this
				, hidden: true
				,	tooltip: this.txtResetLocalTip	
			}]
		,	tools: [{
				id: 'right'
			,	scope: this
			,	qtip: this.txtSwitchToTaxonModeTip
			,	handler: function() {
					this.fireEvent("switchView", "taxonMode", this);
				}
			}]	
	});
	
	TaxonTagger.taggerpanel.superclass.constructor.call(this, config);
	
};

Ext.extend(TaxonTagger.taggerpanel, Ext.ux.ManagedIFramePanel, {
	
		markSciName: function(sel){
			if (sel == '') return;
			var found = true;
			var f = this.getFrameDocument().body;
			Ext.each(Ext.fly(f).select("span.tt-sciname").elements, function() {
				var o2 = Ext.fly( this );
				if(o2.dom.innerHTML.indexOf(sel) != -1){
						found = false
				}
			});
			if (found) {
				
//				var parts = sel.split(" ");  
//				if (parts.length > 1) {
//					parts[0] = parts[0][0] + ".";
//				}
//				abbName = parts.join(" ");
//				if(abbName == sel) {
					this.docBody (sel, sel, sel, sel);
//				} else {
//					this.docBody (sel, sel, sel, sel);
//					this.docBody (abbName, sel, abbName, abbName);
//				}
				Ext.each(TaxonTagger.currentDocument.removedWords, function(item){
					if(item == sel || item == abbName){
						TaxonTagger.currentDocument.removedWords.remove(item);
						this.fireEvent('docDataChanged', this);
					}
				}, this);
				this.generateList();
			}
		}	

	,	docBody: function(sel, sciname, verbatim, orig){
			var b = this.getFrameWindow().document.body;
			var rg = new RegExp(sel, "ig");
			b.innerHTML = b.innerHTML.replace(rg, "<span class=\"tt-sciname manual\" type='Manual' scientificname='" + sciname + "'verbatim='" + verbatim + "' offset='-1'>" + orig + "</span>" +
				"<span class=\"tt-remove manual\" title=\"This removes the scientific name from the list.\">&nbsp;&nbsp;</span>");
		}

	,	updateLocalStorage: function(){
			this.fireEvent('docDataChanged', this);
		}

	,	loadCustomData: function(){
			Ext.each(TaxonTagger.currentDocument.removedWords, function(item){
				this.deleteWord(item);
			}, this);
			Ext.each(TaxonTagger.currentDocument.customWords, function(item){ 
				this.deleteWord(item);
				this.markSciName(item);
			}, this);
		}

	,	deleteWord: function(item){
			var f = this.getFrameDocument().body;
			Ext.each(Ext.fly(f).select("span.tt-remove").elements, function() {
				var o2 = Ext.fly( this );
				var parts = item.split(" "); 
				if (parts.length > 1) {
					parts[0] = parts[0][0] + ".";
				}
				abbName = parts.join(" ");
				if (o2.prev().dom.getAttribute("scientificName") == item) {
					if (o2.prev().dom.getAttribute("verbatim") == abbName) {
						Ext.DomHelper.insertBefore(o2.prev(), abbName);
					} else {
						Ext.DomHelper.insertBefore(o2.prev(), item);
					}
					o2.prev().remove();
					o2.remove();
				} else if (o2.prev().dom.getAttribute("verbatim") == abbName) {
					Ext.DomHelper.insertBefore(o2.prev(), abbName);
					o2.prev().remove();
					o2.remove();
				}
			});
		}

	,	mark: function(o, success, res, request) {
			if (success) {
				this.comboStore(request.params.url);
				this.cssStyle();
				this.removeSciName();
				if (!Ext.isMac && !Ext.isSafari) {
					this.markScientificName.show();
				}
				if(this.toggleScientificName.pressed){
					this.toggleScientificName.doToggle();
				}
				this.toggleScientificName.show();
				this.resetLocal.show();
				this.webLink.show();
				this.fireEvent('afterDocumentLoaded', this, request.params.url);
				this.loadCustomData();
				this.generateList();
				TaxonTagger.docStore.load({params:{start:0, limit: 30}});
			} else {
				TaxonTagger.Notice.msg(this.txtNoticeTitle, this.msgMarkFailure);
			}
		}

	,	isURL: function(s) {
			var regexp = /http:\/\/[A-Za-z0-9\.-]{3,}\.[A-Za-z]{3}/;
			return regexp.test(s);
		}

	,	cssStyle: function(){
			css = new Ext.ux.ManagedIFrame.CSS(this.getFrameDocument());
//			css.createStyleSheet('body{-webkit-user-select: none;}');
			css.createStyleSheet('.tt-remove {'+ 
				'background: #FFFF99 url('+ Config.baseUrl +'resources/images/icons/cancel.png) no-repeat 0 3px;'+
				'cursor: pointer;'+	
				'-webkit-user-select: none;'+
				'-moz-border-radius-bottomright: 3px;'+
				'-moz-border-radius-topright: 3px;'+	
				'border-bottom-right-radius: 3px;'+
				'border-top-right-radius: 3px;'+
				'padding-right: 3px;}'
			);
			css.createStyleSheet('.tt-sciname {'+ 
				'-moz-border-radius-bottomleft:3px;'+
				'-moz-border-radius-topleft:3px;'+
				'border-bottom-left-radius: 3px;'+
				'border-top-left-radius: 3px;'+
				'-webkit-user-select: none;'+
				'background-color:#FFFF99;'+
				'color:red;'+
				'cursor:default;'+
				'padding-left:3px;'+
				'padding-right:5px;}'
			);
			css.createStyleSheet('.manual {'+ 
				'background-color:#FF6600 !important;'+
				'-webkit-user-select: none;'+
				'color: #FFFFFF !important;}'
			);
			css.createStyleSheet('.authorship {'+ 
				'background-color: green !important;'+
				'-webkit-user-select: none;'+
				'color: #FFFFFF !important;}'
			);
			css.createStyleSheet('.highlight_name {'+ 
				'background-color: #EAFDBD !important;'+
				'-webkit-user-select: none;'+
				'color: #000000 !important;}'
			);
		}
		
	,	loadDocument: function(url){
			var serviceName = Ext.decode(localStorage.getItem("settings")) || Config;
			var newService = serviceName["general"]["nfServer"];
			if (Ext.isEmpty(url)) {
				this.setSrc('resources/html/blank-'+lang+'.html');
				TaxonTagger.Notice.msg(this.txtNoticeTitle, this.txtemptyText);
			}	else if (!this.isURL(url)) {
				this.setSrc('resources/html/blank-'+lang+'.html');
				TaxonTagger.Notice.msg(this.txtNoticeTitle, this.txtUrlText);
			} else if(this.lasturlLoaded == url && this.lastService == newService){
				TaxonTagger.Notice.msg(this.txtNoticeTitle, this.msgDocumentAlreadyLoaded);
			} else {
				if(typeof(Ext.getCmp('nubPanel')) != 'undefined'){
					Ext.getCmp('nubPanel').store.removeAll();
					Ext.getCmp('nubPanel').loadedList = false;
					Ext.getCmp('nubPanel').getBottomToolbar().clearStatus();
					Ext.getCmp('nubPanel').getBottomToolbar().setText(Ext.getCmp('nubPanel').bbarTxt);
				}
				this.fireEvent("tabDisable", this);
				this.fireEvent("urlLoaded", url, this);
				this.load({
						url: 'resources/api/transform.php'
					,	params: {
								url: url
							,	service: newService
						}
					,	loadMask: "Loading..."
					,	timeout: 180
					,	scope: this
					,	callback: this.mark
				});
				this.lasturlLoaded = url;
				this.lastService = newService;
				var task = new Ext.util.DelayedTask(function(){
					Ext.getCmp('mifp').getFrame().mask("Analyzing...", 'ext-el-mask-msg x-mask-loading', 'ext-el-mask');
				});
				task.delay(300); 
			}	
		}

	,	comboStore: function( url ){
			if (!Ext.isDefined(typeof(localStorage))) {
			} else {
				var tA = Ext.decode(localStorage.getItem("storedUrls")) || [];
				if (!tA.inArray( url )) {
					tA.unshift(url);
					localStorage.setItem("storedUrls", Ext.encode(tA) );
				}
			}
		}
	
	,	removeSciName: function(){
			var f = this.getFrameDocument().body;
			var mif= Ext.getCmp('mifp');
			Ext.fly(f).on('click', function(e, target) {
				e.stopEvent();
				var o = Ext.fly( this );
				var txt = o.prev().dom.innerHTML;
				var sciname = o.prev().dom.getAttribute("scientificName");
				mif.fireEvent('removeName', o, sciname, txt);
 			}, null, {delegate:'span.tt-remove'});
		}

	,	generateList: function() {
			var serviceName = Ext.decode(localStorage.getItem("settings")) || Config;
			var gridData = [];						
			this.getFrame().select('span.tt-sciname').each(function( el ) {
				var full = '';
				var offset = '';
				var type = '';
				var verbatim = '';
				var scientificname = '';
				var id = '';
				var ct = '';
				Ext.each( el.dom.attributes, function( item ) {
					switch(this.nodeName) {
						case 'full':
							full = this.nodeValue;
							break;
						case 'scientificname':
							scientificname = this.nodeValue;
							break;
						case 'offset':
							offset = this.nodeValue;
							break;
						case 'type':
							type = this.nodeValue;
							break;
						case 'verbatim':
							verbatim = this.nodeValue;
							break;
						case 'id':
							id = this.nodeValue;						
							break;	
						default:
							break;
					}
				});
				if (type == "") {
					type = serviceName["general"]["nfServerName"];
				}	
				gridData.push({
						offset: offset
					,	orig: this.dom.innerHTML
					,	source: type
					,	verbatim: verbatim
					,	id: id
					,	scientificName: scientificname
					,	found:false
					,	processed:false	
					,	frequency:1
					,	comment: ''
				//	,	pro:false
				});
			});
			
			this.updateDocStore(gridData);
			Ext.getCmp('white-list').loadList();
			Ext.getCmp('list-delimited').loadList();
		}

	,	updateDocStore: function(gridData){
			if(this.firstLoad){
				this.firstLoad = false;
				for(var i=0; i < gridData.length; i++){
					var fId = TaxonTagger.docStore.findExact('scientificName',gridData[i].scientificName);
					if(fId == -1){
						TaxonTagger.docStore.loadData(gridData[i],true);
					} else {
						var rec = TaxonTagger.docStore.getAt(fId);
						var newFrq = parseInt(rec.get('frequency'))+1;
						var gridcomment= TaxonTagger.currentDocument.comments[gridData[i].scientificName]
						if(Ext.isDefined(gridcomment) || !Ext.isEmpty(gridcomment)){
							rec.set('comment', gridcomment);
						}
						rec.set('frequency',newFrq);
						rec.commit();
						TaxonTagger.docStore.sort('scientificName', 'ASC');
						TaxonTagger.docStore.commitChanges();
					}
				}
			} else {
				var newSci = [];
				for(var i=0; i < gridData.length; i++){
					var fId = TaxonTagger.docStore.findExact('scientificName',gridData[i].scientificName);
					if(fId == -1){
						newSci.push(gridData[i]);
					}
				}	
				for(var i=0; i < newSci.length; i++){
					var fId = TaxonTagger.docStore.findExact('scientificName',newSci[i].scientificName);
					if(fId == -1){
						TaxonTagger.docStore.loadData([newSci[i]],true);
					} else {
						var rec = TaxonTagger.docStore.getAt(fId);
						var newFrq = parseInt(rec.get('frequency')) + 1;
						var gridcomment = TaxonTagger.currentDocument.comments[gridData[i].scientificName];
						if(Ext.isDefined(gridcomment) || !Ext.isEmpty(gridcomment)){
							rec.set('comment', gridcomment);
						}
						rec.set('frequency',newFrq);
						rec.commit();
						TaxonTagger.docStore.sort('scientificName', 'ASC');
						TaxonTagger.docStore.commitChanges();
					}
				}		
			}
		}	
	
	,	addIframeListeners: function(frame) {
			var el = frame.getDoc();
			el.on('contextmenu', function(e, targetEl){
				e.preventDefault();
				var xy = e.getXY();
				var pXY = this.frameEl.getXY();
				var newX = xy[0]-this.getFrameDoc().getScroll().left + pXY[0];
				var newY = xy[1]-this.getFrameDoc().getScroll().top + pXY[1];
				var sel = this.getFrameWindow().document.getSelection().toString();
				sel = sel.replace(/^\s*|\s*$/g,'');
				sel = sel.trim();
				if(this.menu1) this.menu1.destroy();
				this.menu1 = new Ext.menu.Menu({
					items: [{
							text: 'Parse Name'
						,	scope: this	
						,	ref: 'refParseName'	
						,	hidden: true
						,	handler: function() { 
								this.showParseName(sel)
							}  	
					}, {
							text: 'Mark Scientific Name'
						,	scope: this	
						,	iconCls: 'icon_mark'						
						,	ref: 'refMarkName'
						,	hidden: true
						,	handler: function() {
								if (Ext.isEmpty(sel)) {
									TaxonTagger.Notice.msg(this.txtNoticeTitle, this.msgEmptyMark);
								} else {
									TaxonTagger.currentDocument.customWords.push(sel.trim());
									TaxonTagger.currentDocument.customWords.push(sel.trim);
									this.markSciName(sel);
									this.updateLocalStorage();
								}
							}  	
					}]
				});
				if(!Ext.isEmpty(sel) && this.markScientificName.isVisible()){
					this.menu1.refParseName.show();
					this.menu1.refMarkName.show();
					this.menu1.showAt([newX,newY]);
				}
			}, this, {
					stopEvent: true
				,	preventDefault: true	
			});
			el.on('contextmenu', function(e, targetEl){
				var sel = Ext.getCmp('mifp').getFrameWindow().document.getSelection();
				var f = Ext.getCmp('mifp').getFrameDocument().body;
				if(this.menu) this.menu.destroy();
				this.menu = new Ext.menu.Menu({
						items: [{
						text: 'GBIF Checklist Bank'
					,	ref: 'checkBank'
					,	scope: this	
					,	handler: function() { 
							window.open('http://ecat-dev.gbif.org/search?q=' + targetEl.getAttribute("scientificname") + '&rkey=1', '_blank');
						}  
				}, {
						text: 'Edit Comment'
					,	iconCls: 'icon_comments'
					,	handler: function() { 
							Ext.getCmp('mifp').showComment(targetEl.getAttribute("scientificname"));
						}
				}, {
						text: 'Add ' + sel
					,	ref: 'addAuthor'
					,	scope: this	
					,	hidden: true
					,	handler: function(){
							Ext.each(Ext.fly(f).select("span.tt-sciname").elements, function(el){
								if(targetEl.innerHTML == el.innerHTML){
									var authorship = document.createAttribute('authorship');
									authorship.nodeValue = sel;
									Ext.get(targetEl).addClass('authorship');
									el.attributes.setNamedItem(authorship);
									Ext.get(targetEl.nextSibling).addClass('authorship');
								}
							});
						}  
				}, {
						ref: 'replaceAuthor'	
					,	scope: this	
					,	hidden: true	
					,	handler: function() { 
							Ext.each(Ext.fly(f).select("span.tt-sciname").elements, function(el){
								if(targetEl.innerHTML == el.innerHTML){
									var authorship = document.createAttribute('authorship');
									authorship.nodeValue = sel;
									el.attributes.setNamedItem(authorship);
									Ext.get(targetEl.nextSibling).addClass('authorship');
								}
							});
						}
				}, {
						ref: 'removeAuthor'	
					,	scope: this	
					,	hidden: true	
					,	handler: function() { 
							Ext.each(Ext.fly(f).select("span.tt-sciname").elements, function(el){
								if(targetEl.innerHTML == el.innerHTML){
									Ext.get(targetEl).removeClass('authorship');
									el.attributes.removeNamedItem('authorship');
									Ext.get(targetEl.nextSibling).removeClass('authorship');
								}
							});
						}
				}, {
						text: 'Remove ' + targetEl.getAttribute("scientificname")
					,	scope: this	
					,	handler: function() { 
							Ext.getCmp('mifp').fireEvent('removeName', this, targetEl.getAttribute("scientificname"), targetEl.getAttribute("verbatim"));
						}  	
				}, {
						text: 'Taxamatch'
					,	scope: this	
					,	ref: 'refTaxamatch'	
					,	hidden: true
					,	handler: function() { 
							Ext.getCmp('mifp').showTaxaMatch(targetEl.getAttribute("verbatim"));
						}  	
					}]
				});

				if(targetEl.getAttribute("type") && Config.useTaxamatch){
					this.menu.refTaxamatch.show();
				}
				
				if (!Ext.isEmpty(sel)) {
					var auth = targetEl.getAttribute("authorship");
					if (auth == null) {
						this.menu.addAuthor.show();
					} else if(auth != sel){
						this.menu.replaceAuthor.show();
						this.menu.replaceAuthor.text =  'Replace ' + auth + ' to ' + sel;
					}
				}
				if(targetEl.hasAttribute("authorship")){
					this.menu.removeAuthor.text = 'Remove ' + targetEl.getAttribute("authorship");
					this.menu.removeAuthor.show();
				}
				var xy = e.getXY();
				var pXY = this.getXY();
				var newX = xy[0]-Ext.getCmp('mifp').getFrameDoc().getScroll().left + pXY[0];
				var newY = xy[1]-Ext.getCmp('mifp').getFrameDoc().getScroll().top + pXY[1];
				this.menu.showAt([newX,newY]);
			}, frame, {
					delegate: 'span.tt-sciname'
				,	stopEvent: true
			});
			
			el.on('click', function(event, target) {
				event.stopEvent();
			}, this, {delegate: 'a'});
			
			
			el.on('mouseover', function(e,el1) {
				var title = document.createAttribute('title');
				title.nodeValue = "This removes the scientific name from the list.";
				el1.attributes.setNamedItem(title);
			}, this,{delegate: 'span.tt-remove'});
		}
			
	,	showComment: function(data){
			this.comments = new TaxonTagger.comments({
					title: this.txtComment + data
				,	keyName: data
			});
			this.comments.loadComment();
			this.comments.on("close", this.updateComment, this);
			this.comments.show();
		}

	,	updateComment: function(commentpanel) {
			var index = TaxonTagger.docStore.findExact('scientificName', commentpanel.keyName);
			var rec = TaxonTagger.docStore.getAt(index);
			rec.set('comment', commentpanel.txtComment.getValue());
			rec.commit();
			TaxonTagger.docStore.commitChanges();
			Ext.getCmp('list-delimited').loadList();
		}

	,	showTaxaMatch: function(data){
			this.taxamatch = new TaxonTagger.TaxamatchLookup({
						title: this.titleShowTaxamatch + '(' + data + ')'
					,	keyName: data
				});
			this.taxamatch.txtSearch.setValue(data);		
			this.taxamatch.show();
		}

	,	showParseName: function(data){
			this.parseName = new TaxonTagger.parseName({
					title: data
				,	parsename: data
			});
			this.parseName.show();
		}

});